/// 滑块组件
/// 参照Element UI的Slider控件实现

import 'package:flutter/material.dart';
import '../../core/elegance_theme.dart';
import '../../core/elegance_base.dart';

/// 滑块大小类型枚举
enum ESliderSize {
  /// 小型滑块
  small,
  
  /// 普通大小滑块
  normal,
  
  /// 大型滑块
  large,
}

/// ESlider组件
class ESlider extends EleganceStatefulWidget {
  /// 创建ESlider组件
  const ESlider({
    super.key,
    required this.min,
    required this.max,
    required this.value,
    this.onChanged,
    this.step = 1,
    this.disabled = false,
    this.showTooltip = true,
    this.showStops = false,
    this.showInput = false,
    this.range = false,
    this.vertical = false,
    this.height = 4,
    this.size = ESliderSize.normal,
    this.activeColor,
    this.inactiveColor,
    this.thumbColor,
    this.tooltipFormatter,
    this.markFormatter,
    this.marks,
    this.inputSize,
    this.onAfterChange,
  });

  /// 最小值
  final double min;
  
  /// 最大值
  final double max;
  
  /// 当前值（单一滑块时为double，范围滑块时为List<double>）
  final dynamic value;
  
  /// 值变更回调
  final ValueChanged<dynamic>? onChanged;
  
  /// 步长
  final double step;
  
  /// 是否禁用
  final bool disabled;
  
  /// 是否显示提示
  final bool showTooltip;
  
  /// 是否显示间断点
  final bool showStops;
  
  /// 是否显示输入框
  final bool showInput;
  
  /// 是否为范围滑块
  final bool range;
  
  /// 是否为垂直方向
  final bool vertical;
  
  /// 滑块高度（水平模式）或宽度（垂直模式）
  final double height;
  
  /// 滑块大小
  final ESliderSize size;
  
  /// 激活部分的颜色
  final Color? activeColor;
  
  /// 非激活部分的颜色
  final Color? inactiveColor;
  
  /// 滑块颜色
  final Color? thumbColor;
  
  /// 提示文本格式化器
  final String Function(double)? tooltipFormatter;
  
  /// 标记文本格式化器
  final String Function(double)? markFormatter;
  
  /// 自定义标记
  final Map<double, Widget>? marks;
  
  /// 输入框大小
  final String? inputSize;
  
  /// 拖动结束后的回调
  final ValueChanged<dynamic>? onAfterChange;

  @override
  State<ESlider> createState() => _ESliderState();
}

class _ESliderState extends EleganceState<ESlider> {
  /// 当前值（内部状态）
  dynamic _currentValue;
  
  /// 是否处于拖拽状态
  bool _isDragging = false;
  
  /// 鼠标是否悬浮在滑块上
  bool _isHovered = false;

  @override
  void initState() {
    super.initState();
    _currentValue = widget.value;
  }

  @override
  void didUpdateWidget(covariant ESlider oldWidget) {
    super.didUpdateWidget(oldWidget);
    // 只有在非拖拽状态下才更新值
    if (!_isDragging && oldWidget.value != widget.value) {
      _currentValue = widget.value;
    }
  }

  /// 计算值对应的百分比
  double _getValueToPercentage(double value) {
    return (value - widget.min) / (widget.max - widget.min);
  }

  /// 计算百分比对应的值
  double _getPercentageToValue(double percentage) {
    // 确保百分比在有效范围内
    percentage = percentage.clamp(0.0, 1.0);
    
    // 计算原始值
    double value = widget.min + percentage * (widget.max - widget.min);
    
    // 按步长调整值
    if (widget.step > 0) {
      value = ((value - widget.min) / widget.step).round() * widget.step + widget.min;
    }
    
    return value;
  }

  /// 获取滑块尺寸
  double _getThumbSize() {
    switch (widget.size) {
      case ESliderSize.small:
        return 16.0;
      case ESliderSize.normal:
        return 20.0;
      case ESliderSize.large:
        return 24.0;
      default:
        return 20.0;
    }
  }

  /// 格式化提示文本
  String _formatTooltip(double value) {
    if (widget.tooltipFormatter != null) {
      return widget.tooltipFormatter!(value);
    }
    return value.toStringAsFixed(1);
  }

  /// 获取主题颜色
  Color _getThemeColor(BuildContext context, {bool active = true}) {
    EleganceThemeData? theme = EleganceTheme.of(context);
    if (active) {
      return widget.activeColor ?? theme?.primaryColor ?? Colors.blue;
    } else {
      return widget.inactiveColor ?? theme?.textPlaceholderColor ?? Colors.grey;
    }
  }

  /// 更新滑块值
  void _updateValue(double newValue) {
    if (widget.range) {
      List<double> valueList = List.from(_currentValue as List<double>);
      double leftValue = valueList[0];
      double rightValue = valueList[1];
      
      // 判断点击位置更接近哪个滑块
      if ((newValue - leftValue).abs() < (newValue - rightValue).abs()) {
        valueList[0] = newValue;
      } else {
        valueList[1] = newValue;
      }
      
      // 确保左值小于右值
      valueList.sort();
      _currentValue = valueList;
    } else {
      _currentValue = newValue;
    }
    
    // 通知回调
    if (widget.onChanged != null) {
      widget.onChanged!(_currentValue);
    }
    
    setState(() {});
  }

  /// 处理轨道点击事件
  void _handleTrackTap(Offset localPosition, BoxConstraints constraints) {
    if (widget.disabled || _isDragging) return;
    
    double percentage;
    final thumbSize = _getThumbSize();
    
    if (widget.vertical) {
      // 垂直滑块计算
      double availableHeight = constraints.maxHeight - thumbSize;
      // 计算相对于可用区域的位置百分比
      percentage = 1 - ((localPosition.dy - thumbSize / 2) / availableHeight).clamp(0.0, 1.0);
    } else {
      // 水平滑块计算
      double availableWidth = constraints.maxWidth - thumbSize;
      // 计算相对于可用区域的位置百分比
      percentage = ((localPosition.dx - thumbSize / 2) / availableWidth).clamp(0.0, 1.0);
    }
    
    // 根据百分比计算新值
    double newValue = _getPercentageToValue(percentage);
    _updateValue(newValue);
    
    // 触发结束回调
    if (widget.onAfterChange != null) {
      widget.onAfterChange!(_currentValue);
    }
  }

  /// 处理滑块拖拽事件
  void _handleThumbDragUpdate(DragUpdateDetails details, BoxConstraints constraints) {
    if (widget.disabled || !_isDragging) return;
    
    double percentage;
    final thumbSize = _getThumbSize();
    final renderBox = context.findRenderObject() as RenderBox;
    
    // 获取全局坐标
    final globalPosition = details.globalPosition;
    // 转换为本地坐标
    final localPosition = renderBox.globalToLocal(globalPosition);
    
    if (widget.vertical) {
      // 垂直滑块计算
      double availableHeight = constraints.maxHeight - thumbSize;
      // 计算相对于可用区域的位置百分比
      percentage = 1 - ((localPosition.dy - thumbSize / 2) / availableHeight).clamp(0.0, 1.0);
    } else {
      // 水平滑块计算
      double availableWidth = constraints.maxWidth - thumbSize;
      // 计算相对于可用区域的位置百分比
      percentage = ((localPosition.dx - thumbSize / 2) / availableWidth).clamp(0.0, 1.0);
    }
    
    // 根据百分比计算新值
    double newValue = _getPercentageToValue(percentage);
    _updateValue(newValue);
  }

  @override
  Widget build(BuildContext context) {
    // 获取滑块相关属性
    final thumbSize = _getThumbSize();
    final activeColor = _getThemeColor(context);
    final inactiveColor = _getThemeColor(context, active: false);
    final thumbColor = widget.thumbColor ?? Colors.white;
    
    // 计算激活百分比
    double activePercentage = 0.0;
    List<double> rangePercentages = [0.0, 1.0];
    
    if (widget.range) {
      List<double> valueList = _currentValue as List<double>;
      rangePercentages[0] = _getValueToPercentage(valueList[0]);
      rangePercentages[1] = _getValueToPercentage(valueList[1]);
    } else {
      activePercentage = _getValueToPercentage(_currentValue);
    }
    
    // 创建滑块组件
    Widget slider = LayoutBuilder(
      builder: (context, constraints) {
        // 计算实际尺寸
        final mainAxisExtent = widget.vertical ? 
          (constraints.maxHeight > 0 ? constraints.maxHeight : 200.0) : 
          (constraints.maxWidth > 0 ? constraints.maxWidth : 200.0);
        
        // 构建滑块按钮组件
        Widget buildThumb(double percentage) {
          return AnimatedPositioned(
            duration: Duration(milliseconds: 0), // 立即更新位置
            left: widget.vertical ? null : percentage * (mainAxisExtent - thumbSize),
            bottom: widget.vertical ? percentage * (mainAxisExtent - thumbSize) : null,
            child: MouseRegion(
              onEnter: (_) {
                if (!widget.disabled) {
                  setState(() => _isHovered = true);
                }
              },
              onExit: (_) {
                if (!widget.disabled) {
                  setState(() => _isHovered = false);
                }
              },
              child: GestureDetector(
                onHorizontalDragStart: (_) {
                  if (!widget.disabled) setState(() => _isDragging = true);
                },
                onHorizontalDragUpdate: (details) {
                  if (!widget.vertical) {
                    _handleThumbDragUpdate(details, constraints);
                  }
                },
                onHorizontalDragEnd: (_) {
                  if (!widget.disabled) {
                    setState(() => _isDragging = false);
                    if (widget.onAfterChange != null) {
                      widget.onAfterChange!(_currentValue);
                    }
                  }
                },
                onVerticalDragStart: (_) {
                  if (!widget.disabled) setState(() => _isDragging = true);
                },
                onVerticalDragUpdate: (details) {
                  if (widget.vertical) {
                    _handleThumbDragUpdate(details, constraints);
                  }
                },
                onVerticalDragEnd: (_) {
                  if (!widget.disabled) {
                    setState(() => _isDragging = false);
                    if (widget.onAfterChange != null) {
                      widget.onAfterChange!(_currentValue);
                    }
                  }
                },
                child: Container(
                  width: thumbSize,
                  height: thumbSize,
                  decoration: BoxDecoration(
                    color: thumbColor,
                    border: Border.all(color: activeColor, width: 2),
                    borderRadius: BorderRadius.circular(thumbSize / 2),
                    boxShadow: _isHovered || _isDragging
                        ? [
                            BoxShadow(
                              color: activeColor.withOpacity(0.3),
                              blurRadius: 6,
                              spreadRadius: 1,
                            ),
                          ]
                        : [],
                  ),
                  child: widget.disabled
                      ? Container(
                          width: thumbSize - 4,
                          height: thumbSize - 4,
                          decoration: BoxDecoration(
                            color: Colors.grey.shade300,
                            borderRadius: BorderRadius.circular((thumbSize - 4) / 2),
                          ),
                        )
                      : null,
                ),
              ),
            ),
          );
        }
        
        // 构建轨道组件
        Widget track = Container(
          decoration: BoxDecoration(
            color: inactiveColor,
            borderRadius: BorderRadius.circular(widget.height / 2),
          ),
        );
        
        // 构建激活轨道组件
        Widget activeTrack;
        if (widget.range) {
          // 范围滑块的激活轨道
          activeTrack = Positioned(
            left: widget.vertical ? (widget.height - thumbSize) / 2 : rangePercentages[0] * (mainAxisExtent - thumbSize),
            bottom: widget.vertical ? rangePercentages[0] * (mainAxisExtent - thumbSize) : null,
            width: widget.vertical ? widget.height : (rangePercentages[1] - rangePercentages[0]) * (mainAxisExtent - thumbSize),
            height: widget.vertical ? (rangePercentages[1] - rangePercentages[0]) * (mainAxisExtent - thumbSize) : widget.height,
            child: Container(
              decoration: BoxDecoration(
                color: activeColor,
                borderRadius: BorderRadius.circular(widget.height / 2),
              ),
            ),
          );
        } else {
          // 单滑块的激活轨道
          activeTrack = Positioned(
            left: widget.vertical ? (widget.height - thumbSize) / 2 : 0,
            bottom: widget.vertical ? 0 : null,
            width: widget.vertical ? widget.height : activePercentage * (mainAxisExtent - thumbSize),
            height: widget.vertical ? activePercentage * (mainAxisExtent - thumbSize) : widget.height,
            child: Container(
              decoration: BoxDecoration(
                color: activeColor,
                borderRadius: BorderRadius.circular(widget.height / 2),
              ),
            ),
          );
        }
        
        // 构建滑块列表
        List<Widget> thumbs = [];
        if (widget.range) {
          // 范围滑块的两个滑块
          thumbs.add(buildThumb(rangePercentages[0]));
          thumbs.add(buildThumb(rangePercentages[1]));
        } else {
          // 单滑块
          thumbs.add(buildThumb(activePercentage));
        }
        
        // 构建标记点
        List<Widget> marks = [];
        if (widget.showStops || widget.marks != null) {
          final stepCount = ((widget.max - widget.min) / widget.step).round();
          for (int i = 0; i <= stepCount; i++) {
            final value = widget.min + i * widget.step;
            final percentage = _getValueToPercentage(value);
            
            // 标记点
            marks.add(
              Positioned(
                left: widget.vertical ? (widget.height - 4) / 2 : percentage * (mainAxisExtent - thumbSize) + thumbSize / 2 - 2,
                bottom: widget.vertical ? percentage * (mainAxisExtent - thumbSize) + thumbSize / 2 - 2 : (widget.height - 4) / 2,
                child: Container(
                  width: 4,
                  height: 4,
                  decoration: BoxDecoration(
                    color: activeColor,
                    shape: BoxShape.circle,
                  ),
                ),
              ),
            );
            
            // 标记文本
            if (widget.marks != null && widget.marks!.containsKey(value) && widget.marks![value] != null) {
              final markPosition = widget.vertical 
                ? (percentage * (mainAxisExtent - thumbSize) + thumbSize / 2)
                : (percentage * (mainAxisExtent - thumbSize) + thumbSize / 2);
              
              marks.add(
                Positioned(
                  left: widget.vertical ? thumbSize * 1.5 : markPosition - 20,
                  bottom: widget.vertical ? markPosition - 8 : -24,
                  child: widget.marks![value]!, // 添加非空断言
                ),
              );
            }
          }
        }
        
        // 构建主容器
        return GestureDetector(
          onTapDown: (details) {
            // 处理轨道点击
            final renderBox = context.findRenderObject() as RenderBox;
            final localPosition = renderBox.globalToLocal(details.globalPosition);
            _handleTrackTap(localPosition, constraints);
          },
          child: Container(
            width: widget.vertical ? thumbSize + 8 : mainAxisExtent,
            height: widget.vertical ? mainAxisExtent : thumbSize + 8,
            constraints: BoxConstraints(
              minWidth: widget.vertical ? thumbSize + 8 : 100,
              minHeight: widget.vertical ? 100 : thumbSize + 8,
            ),
            child: Stack(
              alignment: widget.vertical ? Alignment.center : Alignment.centerLeft,
              children: [
                // 非激活轨道
                Positioned(
                  left: widget.vertical ? (thumbSize - widget.height) / 2 : 0,
                  top: widget.vertical ? 0 : (thumbSize - widget.height) / 2,
                  width: widget.vertical ? widget.height : mainAxisExtent,
                  height: widget.vertical ? mainAxisExtent : widget.height,
                  child: track,
                ),
                // 激活轨道
                activeTrack,
                // 滑块按钮
                ...thumbs,
                // 标记
                ...marks,
              ],
            ),
          ),
        );
      },
    );
    
    // 添加输入框（如果需要）
    if (widget.showInput) {
      return Row(
        mainAxisSize: MainAxisSize.min,
        children: [
          SizedBox(
            width: widget.vertical ? null : 200,
            height: widget.vertical ? 200 : null,
            child: slider,
          ),
          SizedBox(width: 8),
          Container(
            padding: EdgeInsets.symmetric(horizontal: 8, vertical: 4),
            decoration: BoxDecoration(
              border: Border.all(color: inactiveColor),
              borderRadius: BorderRadius.circular(4),
            ),
            child: Text(
              widget.range
                  ? '${_formatTooltip((_currentValue as List<double>)[0])} - ${_formatTooltip((_currentValue as List<double>)[1])}'
                  : _formatTooltip(_currentValue),
              style: TextStyle(fontSize: 14),
            ),
          ),
        ],
      );
    }
    
    // 普通滑块
    return SizedBox(
      width: widget.vertical ? null : 200,
      height: widget.vertical ? 200 : null,
      child: slider,
    );
  }
}